home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / mint / shells / bashsrc.zoo / trap.c < prev    next >
C/C++ Source or Header  |  1991-06-05  |  8KB  |  316 lines

  1. /* trap.c -- Not the trap command, but useful functions
  2.    for manipulating those objects.  The trap command is
  3.    in builtins.c */
  4.  
  5. /* Copyright (C) 1987,1989 Free Software Foundation, Inc.
  6.  
  7. This file is part of GNU Bash, the Bourne Again SHell.
  8.  
  9. Bash is free software; you can redistribute it and/or modify it under
  10. the terms of the GNU General Public License as published by the Free
  11. Software Foundation; either version 1, or (at your option) any later
  12. version.
  13.  
  14. Bash is distributed in the hope that it will be useful, but WITHOUT ANY
  15. WARRANTY; without even the implied warranty of MERCHANTABILITY or
  16. FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  17. for more details.
  18.  
  19. You should have received a copy of the GNU General Public License along
  20. with Bash; see the file COPYING.  If not, write to the Free Software
  21. Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
  22.  
  23. #include "trap.h"
  24. #include "shell.h"
  25.  
  26. /* The list of things to do originally, before we started trapping. */
  27. SigHandler *original_signals[NSIG];
  28.  
  29. /* For each signal, a slot for a string, which is a command to be
  30.    executed when that signal is recieved.  The slot can also contain
  31.    DEFAULT_SIG, which means do whatever you were going to do before
  32.    you were so rudely interrupted, or IGNORE_SIG, which says ignore
  33.    this signal. */
  34. char *trap_list[NSIG];
  35.  
  36. /* A translation list so we can be polite to our users. */
  37. char *signal_names[NSIG];
  38.  
  39. static int signal_names_initialized = 0;
  40.  
  41.  
  42. initialize_traps ()
  43. {
  44.   register int i;
  45.  
  46.   if (!signal_names_initialized)
  47.     {
  48.       for (i = 0; i < NSIG; i++)
  49.     signal_names[i] = (char *)NULL;
  50.  
  51.       /* `signal' 0 is what we do on exit. */
  52.       signal_names[0] = "ON_EXIT";
  53.  
  54. #if defined (SIGHUP)        /* hangup */
  55.       signal_names[SIGHUP] = "SIGHUP";
  56. #endif
  57.  
  58. #if defined (SIGINT)        /* interrupt */
  59.       signal_names[SIGINT] = "SIGINT";
  60. #endif
  61.  
  62. #if defined (SIGQUIT)        /* quit */
  63.       signal_names[SIGQUIT] = "SIGQUIT";
  64. #endif
  65.  
  66. #if defined (SIGILL)        /* illegal instruction (not reset when caught) */
  67.       signal_names[SIGILL] = "SIGILL";
  68. #endif
  69.  
  70. #if defined (SIGTRAP)        /* trace trap (not reset when caught) */
  71.       signal_names[SIGTRAP] = "SIGTRAP";
  72. #endif
  73.  
  74. #if defined (SIGABRT)        /*  */
  75.       signal_names[SIGABRT] = "SIGABRT";
  76. #endif
  77.  
  78. #if defined (SIGIOT)        /* IOT instruction */
  79.       signal_names[SIGIOT] = "SIGIOT";
  80. #endif
  81.  
  82. #if defined (SIGEMT)        /* EMT instruction */
  83.       signal_names[SIGEMT] = "SIGEMT";
  84. #endif
  85.  
  86. #if defined (SIGFPE)        /* floating point exception */
  87.       signal_names[SIGFPE] = "SIGFPE";
  88. #endif
  89.  
  90. #if defined (SIGKILL)        /* kill (cannot be caught or ignored) */
  91.       signal_names[SIGKILL] = "SIGKILL";
  92. #endif
  93.  
  94. #if defined (SIGBUS)        /* bus error */
  95.       signal_names[SIGBUS] = "SIGBUS";
  96. #endif
  97.  
  98. #if defined (SIGSEGV)        /* segmentation violation */
  99.       signal_names[SIGSEGV] = "SIGSEGV";
  100. #endif
  101.  
  102. #if defined (SIGSYS)        /* bad argument to system call */
  103.       signal_names[SIGSYS] = "SIGSYS";
  104. #endif
  105.  
  106. #if defined (SIGPIPE)        /* write on a pipe with no one to read it */
  107.       signal_names[SIGPIPE] = "SIGPIPE";
  108. #endif
  109.  
  110. #if defined (SIGALRM)        /* alarm clock */
  111.       signal_names[SIGALRM] = "SIGALRM";
  112. #endif
  113.  
  114. #if defined (SIGTERM)        /* software termination signal from kill */
  115.       signal_names[SIGTERM] = "SIGTERM";
  116. #endif
  117.  
  118. #if defined (SIGCLD)        /* Like SIGCHLD.  */
  119.       signal_names[SIGCLD] = "SIGCLD";
  120. #endif
  121.  
  122. #if defined (SIGPWR)        /* Magic thing for some machines. */
  123.       signal_names[SIGPWR] = "SIGPWR";
  124. #endif
  125.  
  126. #if defined (SIGPOLL)        /* For keyboard input?  */
  127.       signal_names[SIGPOLL] = "SIGPOLL";
  128. #endif
  129.  
  130. #if defined (SIGURG)        /* urgent condition on IO channel */
  131.       signal_names[SIGURG] = "SIGURG";
  132. #endif
  133.  
  134. #if defined (SIGSTOP)        /* sendable stop signal not from tty */
  135.       signal_names[SIGSTOP] = "SIGSTOP";
  136. #endif
  137.  
  138. #if defined (SIGTSTP)        /* stop signal from tty */
  139.       signal_names[SIGTSTP] = "SIGTSTP";
  140. #endif
  141.  
  142. #if defined (SIGCONT)        /* continue a stopped process */
  143.       signal_names[SIGCONT] = "SIGCONT";
  144. #endif
  145.  
  146. #if defined (SIGCHLD)        /* to parent on child stop or exit */
  147.       signal_names[SIGCHLD] = "SIGCHLD";
  148. #endif
  149.  
  150. #if defined (SIGTTIN)        /* to readers pgrp upon background tty read */
  151.       signal_names[SIGTTIN] = "SIGTTIN";
  152. #endif
  153.  
  154. #if defined (SIGTTOU)        /* like TTIN for output if (tp->t_local<OSTOP) */
  155.       signal_names[SIGTTOU] = "SIGTTOU";
  156. #endif
  157.  
  158. #if defined (SIGIO)        /* input/output possible signal */
  159.       signal_names[SIGIO] = "SIGIO";
  160. #endif
  161.  
  162. #if defined (SIGXCPU)        /* exceeded CPU time limit */
  163.       signal_names[SIGXCPU] = "SIGXCPU";
  164. #endif
  165.  
  166. #if defined (SIGXFSZ)        /* exceeded file size limit */
  167.       signal_names[SIGXFSZ] = "SIGXFSZ";
  168. #endif
  169.  
  170. #if defined (SIGVTALRM)        /* virtual time alarm */
  171.       signal_names[SIGVTALRM] = "SIGVTALRM";
  172. #endif
  173.  
  174. #if defined (SIGPROF)        /* profiling time alarm */
  175.       signal_names[SIGPROF] = "SIGPROF";
  176. #endif
  177.  
  178. #if defined (SIGWINCH)        /* window changed */
  179.       signal_names[SIGWINCH] = "SIGWINCH";
  180. #endif
  181.  
  182. #if defined (SIGLOST)        /* resource lost (eg, record-lock lost) */
  183.       signal_names[SIGLOST] = "SIGLOST";
  184. #endif
  185.  
  186. #if defined (SIGUSR1)        /* user defined signal 1 */
  187.       signal_names[SIGUSR1] = "SIGUSR1";
  188. #endif
  189.  
  190. #if defined (SIGUSR2)        /* user defined signal 2 */
  191.       signal_names[SIGUSR2] = "SIGUSR2";
  192. #endif
  193.  
  194.       for (i = 0; i < NSIG; i++)
  195.     if (signal_names[i] == (char *)NULL)
  196.       {
  197.         signal_names[i] = (char *)xmalloc (10 + strlen ("SIGJUNK"));
  198.         sprintf (signal_names[i], "SIGJUNK(%d)", i);
  199.       }
  200.     }
  201.  
  202.  
  203.   for (i = 0; i < NSIG; i++)
  204.     {
  205.       trap_list[i] = (char *)DEFAULT_SIG;
  206.       original_signals[i] = (SigHandler *)signal (i, SIG_DFL);
  207.       signal (i, original_signals[i]);
  208.     }
  209. }
  210.  
  211. /* Return the print name of this signal. */
  212. char *
  213. signal_name (signal)
  214.      int signal;
  215. {
  216.   if (signal > NSIG)
  217.      return ("bad signal number");
  218.   else return (signal_names[signal]);
  219. }
  220.  
  221. /* Turn a string into a signal number, or a number into
  222.    a signal number.  If STRING was "2", "SIGINT", or "INT",
  223.    then (int)2 would be returned. */
  224. int
  225. decode_signal (string)
  226.      char *string;
  227. {
  228.   int sig;
  229.  
  230.   if (sscanf (string, "%d", &sig) == 1) {
  231.     if (sig < NSIG && sig >= 0)
  232.       return (sig);
  233.     else
  234.       return (NO_SIG);
  235.   }
  236.       
  237.   for (sig = 0; sig < NSIG; sig++)
  238.      if ((strcmp (string, signal_names[sig]) == 0) ||
  239.      (strcmp (string, &(signal_names[sig])[3]) == 0))
  240.        return (sig);
  241.   return (NO_SIG);
  242. }
  243.  
  244. sighandler
  245. trap_handler (sig)
  246.      int sig;
  247. {
  248.   if ((sig >= NSIG) || (((int)trap_list[sig]) == 0))
  249.      programming_error ("trap_handler: Bad signal %d", sig);
  250.   else
  251.      parse_and_execute (savestring (trap_list[sig]), "trap");
  252. }
  253.  
  254. /* Set SIG to call STRING as a command. */
  255. void
  256. set_signal (sig, string)
  257.      int sig;
  258.      char *string;
  259. {
  260.   void change_signal ();
  261.  
  262.   if (sig)
  263.     signal (sig, SIG_IGN);
  264.  
  265.   change_signal (sig, savestring (string));
  266.  
  267.   if (sig)
  268.     signal (sig, trap_handler);
  269. }
  270.  
  271. /* If SIG has a string assigned to it, get rid of it.  Then give it
  272.    VALUE. */
  273. void
  274. change_signal (sig, value)
  275.      int sig;
  276.      char *value;
  277. {
  278.   if (((int)trap_list[sig]) > 0)
  279.      free (trap_list[sig]);
  280.   trap_list[sig] = value;
  281. }
  282.  
  283. /* Restore the default action for SIG; i.e., the action the shell
  284.    would have taken before you used the trap command. */
  285. void
  286. restore_default_signal (sig)
  287.      int sig;
  288. {
  289.   signal (sig, original_signals[sig]);
  290.   change_signal (sig, (char *)DEFAULT_SIG);
  291. }
  292.  
  293. /* Make this signal be ignored. */
  294. void
  295. ignore_signal (sig)
  296.      int sig;
  297. {
  298.   signal (sig, SIG_IGN);
  299.   change_signal (sig, (char *)IGNORE_SIG);
  300. }
  301.  
  302. /* Handle the calling of "trap 0".  The only sticky situation is when
  303.    the command to be executed includes an "exit". */
  304. void
  305. run_exit_trap ()
  306. {
  307.   if (((int)trap_list[0]) > 0)
  308.     {
  309.       char *trap_command = savestring (trap_list[0]);
  310.  
  311.       change_signal (0, (char *)NULL);
  312.       parse_and_execute (trap_command, "trap");
  313.     }
  314. }
  315.       
  316.